Parameters, interactivity,
and deployment
School of Mathematical and Physical Sciences
2024-09-27
Deployment
Dashboards are typically just static HTML pages so can be deployed to any web server or web host.
| Static | Rendered a single time (e.g. when underlying data won’t ever change) |
| Scheduled | Rendered on a schedule (e.g. via cron job) to accommodate changing data. |
| Parameterised | Variations of static or scheduled dashboards based on parameters. |
| Interactive | Fully interactive dashboard using Shiny (requires a server for deployment). |
Quarto Pub is a free publishing service for content created with Quarto.
quarto publish command to publish content rendered on your local machine (this is the recommend approach when you are getting started).GitHub, you can use a GitHub Action to automatically render your project and publish the resulting content whenever your code changes.Important
_publish.yml_publish.yml is automatically created (or updated) whenever you execute the quarto publish command, and is located within the project or document directory.
_publish.yml file is used to specify the publishing destination._publish.yml.- source: project
quarto-pub:
- id: "5f3abafe-68f9-4c1d-835b-9d668b892001"
url: "https://njones.quarto.pub/blog"Tip
If you have an existing Quarto Pub site that you want to publish to, you should manually create a _publish.yml file that looks like the example above, but with the appropriate id and url values for your site.
Note
Account information is not stored in _publish.yml, so it is suitable for checking in to version control and being shared by multiple publishers.
Parameters
dashboard-r.qmd
---
title: "Parameters"
format:
dashboard:
logo: images/beetle.png
params:
class: "compact"
---
```{r}
library(ggplot2)
library(dplyr)
mpg <- mpg |>
filter(class == params$class)
```
## Value boxes {height="25%"}
::: {.valuebox icon="car-front-fill" color="info"}
Class
`{r} params$class`
:::
```{r}
#| label: calculate-values
lowest_mileage_cty <- mpg |>
filter(cty == min(cty)) |>
distinct(cty) |>
pull(cty)
highest_mileage_cty <- mpg |>
filter(cty == max(cty)) |>
distinct(cty) |>
pull(cty)
rounded_mean_city_mileage <- mpg |>
summarize(round(mean(cty), 2)) |>
pull()
```
```{r}
#| content: valuebox
#| title: "Least efficient"
#| icon: fuel-pump-fill
#| color: danger
list(
value = paste(lowest_mileage_cty, "mpg")
)
```
```{r}
#| content: valuebox
#| title: "Most efficient"
list(
icon = "fuel-pump",
color = "success",
value = paste(highest_mileage_cty, "mpg")
)
```
::: {.valuebox icon="fuel-pump" color="secondary"}
Average city mileage
`{r} rounded_mean_city_mileage` mpg
:::
## Plots {height="75%"}
```{r}
#| title: Highway vs. city mileage
ggplot(mpg, aes(x = cty, y = hwy)) +
geom_point()
```
```{r}
#| title: Drive types
ggplot(mpg, aes(x = drv)) +
geom_bar()
```dashboard-py.qmd
---
title: "Parameters"
format:
dashboard:
logo: images/beetle.png
params:
class: "compact"
---
```{r}
library(ggplot2)
library(dplyr)
mpg <- mpg |>
filter(class == params$class)
```
## Value boxes {height="25%"}
::: {.valuebox icon="car-front-fill" color="info"}
Class
`{r} params$class`
:::
```{r}
#| label: calculate-values
lowest_mileage_cty <- mpg |>
filter(cty == min(cty)) |>
distinct(cty) |>
pull(cty)
highest_mileage_cty <- mpg |>
filter(cty == max(cty)) |>
distinct(cty) |>
pull(cty)
rounded_mean_city_mileage <- mpg |>
summarize(round(mean(cty), 2)) |>
pull()
```
```{r}
#| content: valuebox
#| title: "Least efficient"
#| icon: fuel-pump-fill
#| color: danger
list(
value = paste(lowest_mileage_cty, "mpg")
)
```
```{r}
#| content: valuebox
#| title: "Most efficient"
list(
icon = "fuel-pump",
color = "success",
value = paste(highest_mileage_cty, "mpg")
)
```
::: {.valuebox icon="fuel-pump" color="secondary"}
Average city mileage
`{r} rounded_mean_city_mileage` mpg
:::
## Plots {height="75%"}
```{r}
#| title: Highway vs. city mileage
ggplot(mpg, aes(x = cty, y = hwy)) +
geom_point()
```
```{r}
#| title: Drive types
ggplot(mpg, aes(x = drv)) +
geom_bar()
```dashboard-py.qmd
---
title: "Parameters"
format:
dashboard:
logo: images/beetle.png
params:
class: "midsize"
---
```{r}
library(ggplot2)
library(dplyr)
mpg <- mpg |>
filter(class == params$class)
```
## Value boxes {height="25%"}
::: {.valuebox icon="car-front-fill" color="info"}
Class
`{r} params$class`
:::
```{r}
#| label: calculate-values
lowest_mileage_cty <- mpg |>
filter(cty == min(cty)) |>
distinct(cty) |>
pull(cty)
highest_mileage_cty <- mpg |>
filter(cty == max(cty)) |>
distinct(cty) |>
pull(cty)
rounded_mean_city_mileage <- mpg |>
summarize(round(mean(cty), 2)) |>
pull()
```
```{r}
#| content: valuebox
#| title: "Least efficient"
#| icon: fuel-pump-fill
#| color: danger
list(
value = paste(lowest_mileage_cty, "mpg")
)
```
```{r}
#| content: valuebox
#| title: "Most efficient"
list(
icon = "fuel-pump",
color = "success",
value = paste(highest_mileage_cty, "mpg")
)
```
::: {.valuebox icon="fuel-pump" color="secondary"}
Average city mileage
`{r} rounded_mean_city_mileage` mpg
:::
## Plots {height="75%"}
```{r}
#| title: Highway vs. city mileage
ggplot(mpg, aes(x = cty, y = hwy)) +
geom_point()
```
```{r}
#| title: Drive types
ggplot(mpg, aes(x = drv)) +
geom_bar()
```Use the -P command line option to vary the parameter:
dashboard-py.qmd
---
title: "Valueboxes"
format: dashboard
---
```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```
```{python}
#| tags: [parameters]
car_class = "compact"
```
```{python}
#| label: filter-for-class
filtered_mpg = mpg[mpg['class'] == car_class]
filtered_mpg.reset_index(drop=True, inplace=True)
```
## Value boxes {height="25%"}
::: {.valuebox icon="car-front-fill" color="info"}
Class
`{python} car_class`
:::
```{python}
#| label: calculate-values
lowest_mileage_index = filtered_mpg['cty'].idxmin()
lowest_mileage_car = filtered_mpg.iloc[lowest_mileage_index]
lowest_mileage_cty = filtered_mpg.loc[lowest_mileage_index, 'cty']
highest_mileage_index = filtered_mpg['cty'].idxmax()
highest_mileage_car = filtered_mpg.iloc[highest_mileage_index]
highest_mileage_cty = filtered_mpg.loc[highest_mileage_index, 'cty']
mean_city_mileage = filtered_mpg['cty'].mean()
rounded_mean_city_mileage = round(mean_city_mileage, 2)
```
```{python}
#| content: valuebox
#| title: "Least efficient"
#| icon: fuel-pump-fill
#| color: danger
dict(
value = str(f"{lowest_mileage_cty} mpg")
)
```
```{python}
#| content: valuebox
#| title: "Most efficient"
dict(
icon = "fuel-pump",
color = "success",
value = str(f"{highest_mileage_cty} mpg")
)
```
::: {.valuebox icon="fuel-pump" color="secondary"}
Average city mileage
`{python} str(rounded_mean_city_mileage)` mpg
:::
## Plots {height="75%"}
```{python}
#| title: Highway vs. city mileage
(
ggplot(filtered_mpg, aes(x = "cty", y = "hwy"))
+ geom_point()
)
```
```{python}
#| title: Drive types
(
ggplot(filtered_mpg, aes(x = "drv"))
+ geom_bar()
)
```Interactivity
The Shiny package (for R and for Python) provides an easy way to build web applications with R.
Quarto dashboards can include embedded Shiny components (e.g., a plot with sliders that control its inputs) to add interactivity.
Ladder of complexity/customization: Quarto dashboard > Quarto dashboard with Shiny components > Shiny dashboard
Observable JS for client-side interactivity using the Observable dialect of JavaScript.
Jupyter Widgets or htmlwidgets for client-side interactivity based on standard Python and R JavaScript widget frameworks.
R: Work on your best version of olympicdash-r-3.qmd or olympicdash-r-4.qmd in your cloned olympicdash folder.
Python: Work on your best version of olympicdash-py-3.qmd or olympicdash-py-4.qmd in your cloned olympicdash folder.
Deploy your latest dashboard to QuartoPub.
Stretch goal: Add parameter and/or interactivity to your dashboard for narrowing down to or picking a year.
R, you can use the plotly package & applying ggplotly to give some interactivity to your ggplots.10:00